<?php

namespace App\Controllers;

use App\Models\MasterUser;
use App\Services\AdminService;
use App\Services\MasterLogService;
use App\Services\RoleService;
use App\Services\MenuService;
use common\enum\CommonEnum;
use common\enum\MasterLogEnum;
use common\utils\RedisKeys;
use common\utils\SysCode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redis;

class AuthController extends BaseController
{
    public $allows = ['login', 'timezone','logout'];

    public function login(Request $request)
    {
        $this->validate($request, [
            'username' => 'required',
            'password' => 'required',
        ]);
        $credentials = $request->only('username', 'password');
        $token = Auth::attempt($credentials);
        $remark = str_replace(['{:name}'], [$request->input('username')], MasterLogEnum::REMARK['admin_login']);
        if (!$token) {
            MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGIN, MasterLogEnum::FAIL, $remark);
            return error_exit(SysCode::USER_AUTH_NOT_MATCH);
        }
        $user = Auth::user();
        //验证用户状态
        if ($user->status == CommonEnum::DISABLE){
            MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGIN, MasterLogEnum::FAIL, $remark);
            error_exit(SysCode::ADMIN_USER_STATE_ERROR);
        }
        if ($user->status == CommonEnum::DELETE){
            MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGIN, MasterLogEnum::FAIL, $remark);
            error_exit(SysCode::ADMIN_USER_DELETED);
        }
        //验证过期时间
        if (!empty($user['expire_time']) && strtotime($user->expire_time) <= time()){
            MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGIN, MasterLogEnum::FAIL, $remark);
            error_exit(SysCode::ADMIN_USER_OUT_OF_DATE);
        }
        //验证白名单
        if ($user->white_list){
            $white_list = explode(",",$user->white_list);
            if (!in_array($user->loginip,$white_list)){
                MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGIN, MasterLogEnum::FAIL, $remark);
                error_exit(SysCode::ADMIN_USER_IP_ERROR);
            }
        }
        //数据操作
        $auth = RoleService::roleAuthList(['role'=>$user['role']]);
        $redis = Redis::connection();
        $key = RedisKeys::KICK_ADMIN.$user['id'];
        $isKicked = $redis->get($key);
        if ($isKicked){
            $redis->del($key);
        }
        $updateLoginMsg = [
            'loginip'=> $request->ip(),
            'logintime'=>date('Y-m-d H:i:s')
        ];
        MasterUser::where(['id'=>$user['id']])->update($updateLoginMsg);
        $menu = MenuService::menuList($user['role']);
        $res = [
            'user' => $user,
            'token' => $token,
            'routes' => $auth['routes'],
            'menu'=>$menu
        ];
        MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGIN, MasterLogEnum::SUCCESS, $remark);
        return $res;
    }

    public function logout()
    {
        $user = Auth::user();
        $remark = str_replace('{:name}', !empty($user['username']) ? $user['username'] : '', MasterLogEnum::REMARK['admin_logout']);
        MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_LOGOUT, MasterLogEnum::SUCCESS, $remark);
        return Auth::logout();
    }

    /**
     * 返回服务器时间
     */
    public function timezone(){
        return [
            'timezone_name' => env('DB_TIMEZONE', '+00:00') == '+08:00' ? '北京时间' : '美东时间',
            'timezone' => 'UTC/GMT ' . env('DB_TIMEZONE', '+00:00'),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    /**
     * 修改密码
     * @param Request $request
     * @return mixed
     * @throws \App\Exceptions\CustomException
     * @throws \Illuminate\Validation\ValidationException
     */
    public function editPassword(Request $request)
    {
        $this->validate($request, [
            'new' => 'required',
            'old' => 'required',
        ]);

        $data = $request->input();
        return AdminService::editPwd($data);
    }
}
